<?php
/*******************************************************************************
 *  Copyright IBM Corp. 2007 All rights reserved.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *********************************************************************************/


/**
 * The Connection Class is used to create a connection to either a DB2, Apache Derby or Cloudscape
 * database. It supports either a direct connection to a hostname and port number
 * or a connection through a DB2 Client.
*/

/** Statement Class */
require_once 'DBConnection.php';
require_once 'DBStatement_IBM_DB2.php';
/** The Connection Class is used to create a connection to either a DB2, Apache Derby or Cloudscape
 * database. It supports either a direct connection to a hostname and port number
 * or a connection through a DB2 Client. */
class Connection_IBM_DB2 extends Connection {

	/** Indicated the PHP extension used
	 * set to null if non is needed
	 * @var string */
	public static $requiredDBExtension = "ibm_db2";
	/** Indicated the PHP extension minimum version needed
	 * set to null if non is needed
	 * @var float */
	public static $requiredDBExtensionMinVersion = 1.6;
	/** Database Managment System
	 * @var float */
	public static $DBMS = "DB2";
	
	public $statementClass = "Statement_IBM_DB2";

	public function driverCheck()
	{
		if(ENABLE_PHP_EXTENSION_CHECK)
		{
			$extension_version = phpversion(Connection_IBM_DB2::$requiredDBExtension);
			if($extension_version === false)
			{
				$this->SQLState = -1;
				$this->SQLErrorMSG = "The " . Connection_IBM_DB2::$requiredDBExtension . " PHP module was not found.";
				return false;
			}
			elseif($extension_version < Connection_IBM_DB2::$requiredDBExtensionMinVersion)
			{
				$this->SQLState = -2;
				$this->SQLErrorMSG = "Upgrade to latest " . Connection_IBM_DB2::$requiredDBExtension . " PHP module. v" . $extension_version . " is installed a minimum of v" .Connection_IBM_DB2::$requiredDBExtensionMinVersion . "  is required.";
				return false;
			}
		}
		return true;
	}
	
	public function newStatement($stmt_text, $prepare_statment = FALSE, $verbose = FALSE, $ForwardOnlyScroll = TRUE, $getRowCount = FALSE)
	{
		return new Statement_IBM_DB2($stmt_text, $prepare_statment, $verbose, $ForwardOnlyScroll, $getRowCount, $this);
	}

	/**
	  * Requires a database name, schema, userid and password.
	  * If the hostname and portnumber are also included it will try to connect directly to the database.
	  * With only a database name, it will try to connect through a local DB2 Client.
	*/
	public function __construct($database, $schema, $username, $password, $hostname, $portnumber, $usePersistentConnection = USE_PERSISTENT_CONNECTION, $enableTrustedContext = false) {

		if(!@$this->driverCheck()) return;

		$usePersistentConnection = $usePersistentConnection == "" || $usePersistentConnection == null ? USE_PERSISTENT_CONNECTION : $usePersistentConnection;

		$this->description = $username . "@" . $database . ($hostname != "" ? "." . $hostname . ":" . $portnumber : "" );
		$this->database = $database;
		$this->schema = $schema =! "" && $schema != null ? $schema : $username;
		$this->username = $username;
		$this->password = $password;
		$this->hostname = $hostname;
		$this->portnumber = $portnumber;
		$this->usePersistentConnection = $usePersistentConnection;

		$this->trustedContextEnabled = $enableTrustedContext;

        if(trim($this->description) == "@")
            $this->description = "";

        $this->cataloged = ($this->hostname == "" | $this->portnumber == "") ? true : false;

		if($this->database == "" && $this->username == "")
			return;

		$optionArray = array();

		if($this->trustedContextEnabled)
		{
			$optionArray['trustedcontext'] = DB2_TRUSTED_CONTEXT_ENABLE;
		}
		/** db2_connect returns 0 if the connection attempt fails;
		  * otherwise it returns a connection ID used by other DB2 functions */

		if($this->usePersistentConnection)
		{
			if ($this->cataloged) {
				$this->dbconn = db2_pconnect($this->database, $this->username, $this->password, $optionArray);
			}
			else {
				$connectionString = "HOSTNAME=$this->hostname;DATABASE=$this->database;PROTOCOL=TCPIP;PORT=$this->portnumber;UID=$this->username;PWD=$this->password;";
				$this->dbconn = db2_pconnect($connectionString, NULL, NULL, $optionArray);
			}
		}
		else
		{
			if ($this->cataloged) {
				$this->dbconn = db2_connect($this->database, $this->username, $this->password, $optionArray);
			}
			else {
				$connectionString = "HOSTNAME=$this->hostname;DATABASE=$this->database;PROTOCOL=TCPIP;PORT=$this->portnumber;UID=$this->username;PWD=$this->password;";
				$this->dbconn = db2_connect($connectionString, NULL, NULL, $optionArray);
			}
		}

		if ($this->dbconn === false) {
			$this->SQLState = db2_conn_error();
			$this->SQLErrorMSG = db2_conn_errormsg();
			if (DEBUG_MODE_ENABLED && db2_conn_errormsg() != "") {
				echo("Connection to database failed.");
				$sqlerror = $this->SQLErrorMSG;
				echo($sqlState);
			}
			$this->connected = false;

		}
		else {

			$time = date('y.d.m:H:i:s');
			$options = array(
					'wrkstnname' => 'TEr' . MAJOR_VERSION . "." . MINOR_VERSION . "." . SUB_VERSION . '_on_' . $username . "@" . $_SERVER['SERVER_ADDR'] . "_FROM_" . $_SERVER['REMOTE_ADDR'] . "_at_" . $time,
					'applname' => 'TEr' . MAJOR_VERSION . "." . MINOR_VERSION . "." . SUB_VERSION . '_on_' . $username . "@" . $_SERVER['SERVER_ADDR'] . "_FROM_" . $_SERVER['REMOTE_ADDR'] . "_at_" . $time
					);

			db2_set_option($this->dbconn, $options, 1);


			$this->setSchema();
			$this->connected = true;
		}
		if($this->cataloged = "")
		{
			$this->hostname = "LOCAL";
			$this->portnumber = "LOCAL";
		}
	}
	public function setTrustedContextUsers($userName, $password)
	{
		if(!$this->trustedContextEnabled || $this->dbconn === false)
		{
			$this->connected = false;
			$this->SQLErrorMSG = 'Trusted context has not been enabled.';
			$this->dbconn = false;
			return $this;
		}

		if(!db2_get_option($this->dbconn, "trustedcontext"))
		{
			$this->connected = false;
			$this->SQLErrorMSG = 'Trusted context has not been enabled on this connection.';
			$this->dbconn = false;
			return $this;
		}

		if(db2_set_option($this->dbconn, array('trusted_user' => $userName, 'trusted_password' => $password), 1))
		{
			if($userName == db2_get_option($this->dbconn, "trusted_user"))
			{
				$this->connected = true;
				$this->SQLErrorMSG = 'User has been switched.';
				return $this;
			}
		}
		$this->connected = false;
		$this->SQLErrorMSG = 'Could not set trusted context user.';
		$this->dbconn = false;
		return $this;
	}

	/**
	 * Sets the autocommit
	 * @return resource
	 */
	public function setAutoCommit($SQLAdHoc_AutoCommit) {
		return @db2_autocommit($this->dbconn, $SQLAdHoc_AutoCommit);
	}

	/**
	 * executs a commit
	 * @return resource
	 */
	public function commit() {
		return @db2_commit($this->dbconn);
	}

	/**
	 * Executs a rollback
	 * @return resource
	 */
	public function rollback() {
		return @db2_rollback($this->dbconn);
	}

	/**
	 * Sets the database schema for all subsequent database requests.
	 *
	 * If the schema variable is blank the schema is set by default
	 * to the schema corresponding to the username.
	 */
	public function setSchema($schema = null) {
		$setCurrentPath = "SET CURRENT PATH ";
		$setCurrentSchema = "SET CURRENT SCHEMA ";
		if($schema != null && $schema != "" && strtolower($this->schema) != strtolower($this->username))
		{
			$setCurrentPath .= $schema . ", USER, SYSTEM PATH";
			$setCurrentSchema .= $schema;
			@db2_exec($this->dbconn, $setCurrentPath);
			@db2_exec($this->dbconn, $setCurrentSchema);
		}
		else if ($this->schema != "" && strtolower($this->schema) != strtolower($this->username)) {
			$setCurrentPath .= $this->schema . ", USER, SYSTEM PATH";
			$setCurrentSchema .= $this->schema;
			@db2_exec($this->dbconn, $setCurrentPath);
			@db2_exec($this->dbconn, $setCurrentSchema);
		}
	}

	public function setDescription($description) {
		$this->description = $description;
	}

	/**
	 * Close the database connection.
	 */
	public function close() {
		db2_close($this->dbconn); // Close the connection
	}

}
